import zqdb.strategy as zqdb

class DMA(zqdb.Strategy):
    """"""

    default_setting = {
        'type': '趋势',
        'name': '双MA策略',
        'desc': '双MA策略',
        'trigger':zqdb.TRIGGER_TYPE.BAR,
        'input': {
            'fast_window': 5,
            'slow_window': 20,
            "volume": 0.0
        }
    }

    def __init__(
        self,
        setting: dict
    ):
        """Constructor"""
        super().__init__(setting)
        input = setting["input"]
        self.fast_window = input["fast_window"]
        self.slow_window = input["slow_window"]
        self.volume = input["volume"]

    # 启动时调用
    def on_start(self):
        """"""
        self.infos = {}
        i = 0
        j = self.count
        while(i < j):
            code = zqdb.Code(i)
            info = zqdb.Info()
            info.fast_ma_buffer = zqdb.MABuffer(zqdb.DATA.CLOSE, self.fast_window, zqdb.MAType.SMA, code)  # 引用FAST MA指标索引0的数据
            info.slow_ma_buffer = zqdb.MABuffer(zqdb.DATA.CLOSE, self.slow_window, zqdb.MAType.SMA, code)  # 引用SLOW MA指标索引0的数据
            self.infos[code.Code] = info
            i = i + 1
        pass

    # 停止时调用
    def on_stop(self):
        """"""
        pass
   
    # 计算函数，当关联的计算数据/指标等更新时就会被调用，策略算法可以调用交易相关函数
    def on_calc(self, code):
        """"""
        # 计算数据更新通知，如果关联了计算数据/指标，当计算数据/指标更新时就会收到通知
        # 指标/策略计算请在这里编写...

        user = self.user
        if not user:
            zqdb.LogInfo(str(("双MA策略运行失败，交易账号为空")))
            return

        info = self.infos.get(code.Code)
        if not info:
            zqdb.LogInfo(str((code.Code, "没有找到对应信息")))
            return

        cross = zqdb.CROSS(info.fast_ma_buffer, info.slow_ma_buffer)
        if cross == 0:
            return

        volume = volume = self.volume if self.volume > 0 else self.order_default_volume(code)     
        long_position = zqdb.Position(user, code, zqdb.DIRECTION_TYPE.LONG)
        short_position = zqdb.Position(user, code, zqdb.DIRECTION_TYPE.SHORT)
       
        if cross > 0:
            # cross_over
            if short_position:
                avail_volume = short_position.Volume - short_position.FrozenVolume
                zqdb.LogInfo(code.Code, "平仓", short_position.Volume, short_position.FrozenVolume, volume)
                close_volume = volume
                if close_volume <= 0 or close_volume > avail_volume:
                    close_volume = avail_volume
                if close_volume > 0:
                    orderid = self.order_close(short_position, zqdb.ORDER_TYPE.MARKET, code.Close, close_volume)
                    
            self.order_send(code, zqdb.DIRECTION_TYPE.LONG, zqdb.ORDER_TYPE.MARKET, code.Close, volume)

        elif cross < 0:
            # cross_below
            if long_position:
                avail_volume = long_position.Volume - long_position.FrozenVolume
                zqdb.LogInfo(code.Code, "平仓", long_position.Volume, long_position.FrozenVolume, volume)
                close_volume = volume
                if close_volume <= 0 or close_volume > avail_volume:
                    close_volume = avail_volume
                if close_volume > 0:
                    orderid = self.order_close(long_position, zqdb.ORDER_TYPE.MARKET, code.Close, close_volume)
                    
            self.order_send(code, zqdb.DIRECTION_TYPE.SHORT, zqdb.ORDER_TYPE.MARKET, code.Close, volume)
